package com.sec.android.app.myfiles.module.abstraction;

import android.content.Context;
import android.net.Uri;

import com.sec.android.app.myfiles.feature.LockUnlockMgr;
import com.sec.android.app.myfiles.info.AppFeatures;
import com.sec.android.app.myfiles.info.FileType;
import com.sec.android.app.myfiles.info.MediaFile;
import com.sec.android.app.myfiles.info.MimeType;
import com.sec.android.app.myfiles.module.ModuleLoader;
import com.sec.android.app.myfiles.util.securefolder.SecureConstants;

public abstract class FileRecord {

    public enum StorageType {
        Local,
        SecureLocal,
        Category,
        Downloads,
        Cloud,
        Zip,
        Samba,
        Home,
        Recent,
        Blank,
        Search,
        Shortcut,
        S_Finder,
        Compress,
        FolderTree,
        Suggestion,
        OptimizeStorage,
        Trash,
        None
    }

    public enum CategoryType {
        Image,
        Video,
        Audio,
        Document,
        Apk,
        Folder,
        None
    }

    public enum CloudType {
        SamsungDrive,
        GoogleDrive,
        None
    }

    public enum ShortcutType {
        HomeScreen,
        MyFiles,
    }

    public enum OptimizeStorageType {
        Overview,
        LargeFiles,
        UnusedFiles,
        UnnecessaryData,
        DuplicateFiles,
        PotentialSpaceSize,
        None
    }

    protected int mId = -1;
    protected String mPath;
    protected String mName;
    protected String mMimeType;
    protected long mSize;
    protected long mDate;
    protected int mFileType;
    protected int mIsHidden;
    protected int mItemCount;
    protected int mItemCountHidden;
    protected boolean mIsGear360Contents;

    protected StorageType mStorageType;
    protected StorageType mCreatedFrom = StorageType.None;
    protected Uri mUri;

    // for Tablet Left shortcut record
    private StorageType mPreStorageType = StorageType.None;

    public abstract String getDisplayName(Context context);

    public abstract boolean isRoot();

    public abstract boolean exists(Context context);

    protected abstract int _getId();

    protected abstract Uri _getUri(Context context);

    public static FileRecord createFileRecord(StorageType storageType, String fullPath) {
        return ModuleLoader.getInstance().createFileRecord(storageType, fullPath);
    }

    public static FileRecord createFileRecord(StorageType storageType, int id, String path, String name, long size, long date, int fileType,
                                              int isHidden, int itemCount, int itemCountHidden) {
        return ModuleLoader.getInstance().createFileRecord(storageType, id, path, name, size, date, fileType, isHidden, itemCount,
                itemCountHidden);
    }

    protected FileRecord() {
    }

    protected FileRecord(StorageType storageType, int id, String path, String name, long size, long date, int fileType, int isHidden,
                         int itemCount, int itemCountHidden) {
        mId = id;
        mStorageType = storageType;
        mPath = path;
        mName = name;
        mSize = size;
        mDate = date;
        mFileType = fileType;
        mIsHidden = isHidden;
        mItemCount = itemCount;
        mItemCountHidden = itemCountHidden;
    }

    public FileRecord getParent() {
        FileRecord ret = null;

        if (!isRoot()) {
            String parentPath = this.getPath();
            if (parentPath != null) {
                ret = FileRecord.createFileRecord(this.getStorageType(), this.getPath());
            }
        }

        return ret;
    }

    /**
     * get Parent record which real exist.
     *
     * @param mContext
     * @return
     */
    public FileRecord getParent(Context mContext) {
        FileRecord ret = this;
        do {
            ret = ret.getParent();
        } while (ret != null && !ret.exists(mContext));
        return ret;
    }

    public final Uri getUri(Context context) {
        if (mUri == null) {
            mUri = _getUri(context);
        }

        return mUri;
    }

    public int getId() {
        if (mId < 0) {
            mId = _getId();
        }

        return mId;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public void setPath(String path) {
        mPath = path;
    }

    public String getNameWithoutExt() {
        String ret = mName;
        if (mName != null && !isDirectory()) {
            int indexOfDot = mName.lastIndexOf('.');
            if (LockUnlockMgr.getInstance().isEncryptionFile(mName)) {
                int temp = indexOfDot;
                indexOfDot = mName.substring(0, indexOfDot).lastIndexOf('.');
                if (indexOfDot < 0) {
                    indexOfDot = temp;
                }
            }

            if (indexOfDot > 0) {
                ret = mName.substring(0, indexOfDot);
            }
        }
        return ret;
    }

    public static String getPath(String fullPath) {
        String ret = null;
        if (fullPath != null) {
            int lastSlash = fullPath.lastIndexOf('/');

            if (lastSlash >= 0) {
                ret = fullPath.substring(0, lastSlash);
            }
        }
        return ret;
    }

    public static String getName(String fullPath) {
        String ret = null;
        if (fullPath != null) {
            int lastSlash = fullPath.lastIndexOf('/');

            if (lastSlash >= 0) {
                ret = fullPath.substring(lastSlash + 1, fullPath.length());
            } else {
                ret = fullPath;
            }
        }

        return ret;
    }

    public static String getFullPath(String path, String name) {
		String fullPath = "";
		
		//TODO HYL - Privatefolder 根目录  这只是workaround ！！！！
		if (path != null && path.startsWith(SecureConstants.privateRecoveryRootPath) && "0".equals(name)) {
			fullPath = path;
		} else {
			fullPath = path + "/" + name;
		}
		
        return fullPath;
    }

    public String getPath() {
        return mPath;
    }

    public String getFullPath() {
        return getFullPath(mPath, mName);
    }

    public long getSize() {
        return mSize;
    }

    public String getExt() {
        String ret = null;
        if (!isDirectory()) {
            ret = getExt(mName);
        }
        return ret;
    }

    public String getExtForRename() {
        if (isEncryptionFileType())
            return getExtEncryptionFile(mName);
        else
            return getExt();
    }

    public static String getExt(String path) {
        String ret = "";
        if (path != null) {
            int lastDot = path.lastIndexOf('.');
            if (lastDot >= 0) {
                ret = path.substring(lastDot + 1);
            }
        }

        return ret;
    }

    public static String getExtEncryptionFile(String path) {
        String ret = "";
        String encExt = "";

        int lastDot = path.lastIndexOf('.');
        if (lastDot != -1) {
            encExt = path.substring(lastDot, path.length());
            path = path.substring(0, lastDot);
        }
        lastDot = path.lastIndexOf('.');
        if (lastDot != -1) {
            String ext = path.substring(lastDot + 1, path.length());
            StringBuilder sb = new StringBuilder(ext);
            sb.append(encExt);
            ret = sb.toString();
        }

        return ret;

    }

    public long getDate() {
        return mDate;
    }

    public void setFileType(int fileType) {
        mFileType = fileType;
    }

    public int getFileType() {
        return mFileType;
    }

    public boolean isGear360Contents() {
        return mIsGear360Contents;
    }

    public void setGear360Contents(boolean isGear360Contents) {
        if (AppFeatures.SUPPORT_GEAR360) {
            mIsGear360Contents = isGear360Contents;
        } else {
            mIsGear360Contents = false;
        }
    }

    public int getHidden() {
        return mIsHidden;
    }

    public int getItemCount(boolean showHidden) {
        int nRet = mItemCount;

        if (showHidden) {
            nRet = mItemCountHidden;
        }

        return nRet;
    }

    public StorageType getStorageType() {
        return mStorageType;
    }

    public boolean isDirectory() {
        return (mFileType == FileType.FOLDER);
    }

    public String getMimeType(Context context) {
        if (mMimeType == null) {
            mMimeType = MediaFile.getMimeType(context, getFullPath());

            if (mMimeType == null) {
                mMimeType = MimeType.DEFAULT;
            }
        }

        return mMimeType;
    }

    public void setMimeType(String mimeType) {
        mMimeType = mimeType;
    }

    public boolean isAudioFileType() {
        return FileType.isAudioFileType(getFileType());
    }

    public boolean isVideoFileType() {
        return FileType.isVideoFileType(getFileType());
    }

    public boolean isPlayableFileType() {
        return FileType.isVideoFileType(getFileType()) || FileType.isAudioFileType(getFileType());
    }

    public boolean isImageFileType() {
        return FileType.isImageFileType(getFileType());
    }

    public boolean isPlayListFileType() {
        return FileType.isPlayListFileType(getFileType());
    }

    public boolean isDocumentFileType() {
        return FileType.isDocumentFileType(getFileType());
    }

    public boolean isApkFileType() {
        return FileType.isApkFileType(getFileType());
    }

    public boolean isOtherFileType() {
        return !isAudioFileType() && !isVideoFileType() && !isImageFileType() && !isDocumentFileType();
    }

    public boolean isEncryptionFileType() {
        return FileType.isEncryptionFileType(getFileType());
    }

    /**
     * check isChildRecord is ChildPath of this. this and isChildRecord have to
     * be directory.
     *
     * @param isChildDir file record
     * @return true/false
     */
    public boolean isChildDirectory(FileRecord isChildDir) {
        boolean bRet = false;

        if (isDirectory() && isChildDir.isDirectory()) {
            if (getStorageType() == isChildDir.getStorageType()) {
                String fullPath = getFullPath() + "/";
                String child = isChildDir.getFullPath();
                if (child.startsWith(fullPath)) {
                    bRet = true;
                }
            }
        }

        return bRet;
    }

    @Override
    public boolean equals(Object o) {
        boolean bRet = false;

        if (o instanceof FileRecord) {
            FileRecord cmp = (FileRecord) o;
            if (cmp.getStorageType() == getStorageType() && (cmp.getFullPath() != null && cmp.getFullPath().equals(getFullPath()))) {
                bRet = true;
            }
        } else {
            bRet = super.equals(o);
        }

        return bRet;
    }

    @Override
    public int hashCode() {
        int initValue = 631; // randomly chosen prime numbers
        int constant = 2971; // randomly chosen prime numbers

        int nRet = initValue;
        nRet += mStorageType.hashCode() * constant;
        if (mPath != null) {
            nRet += mPath.hashCode() * constant;
        }

        if (mName != null) {
            nRet += mName.hashCode() * constant;
        }

        return nRet;
    }

    /**
     * check path name is not null and not ""
     *
     * @return true/false
     */
    public boolean isValidFullPath() {
        boolean bRet = false;

        if (mPath != null && mName != null) {
            if (!mPath.isEmpty() && !mName.isEmpty()) {
                bRet = true;
            }
        }

        return bRet;
    }

    Object mDetailMediaInfo[];

    public void setDetailMediaInfo(Object[] detailMediaInfo) {
        mDetailMediaInfo = detailMediaInfo;
    }

    public Object[] getDetailMediaInfo() {
        return mDetailMediaInfo;
    }

    public String getKey() {
        StringBuilder sb = new StringBuilder();
        sb.append(getStorageType());
        sb.append(',');
        sb.append(getFullPath());
        sb.append(',');
        sb.append(getSize());
        sb.append(',');
        sb.append(getDate());
        return sb.toString();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(mStorageType);
        sb.append('-');
        sb.append(getFullPath());
        return sb.toString();
    }

    public void setStorageType(StorageType type) {
        mStorageType = type;
    }

    public void setItemCount(int itemCount, boolean showHidden) {
        if (showHidden) {
            mItemCountHidden = itemCount;
        } else {
            mItemCount = itemCount;
        }
    }

    public void initItemCount() {
        mItemCountHidden = -1;
        mItemCount = -1;
    }

    public StorageType whereAreYouFrom() {
        return mCreatedFrom;
    }

    public void setCreatedFrom(StorageType storageType) {
        mCreatedFrom = storageType;
    }

    public StorageType getPreStorageType() {
        return mPreStorageType;
    }

    public void setPreStorageType(StorageType preStorageType) {
        mPreStorageType = preStorageType;
    }
}
